package models.users

import javax.inject.{Inject, Singleton}
import play.api.db.slick.{DatabaseConfigProvider, HasDatabaseConfigProvider}
import slick.jdbc.JdbcProfile

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class AppNasUsersRepository @Inject()(protected val dbConfigProvider: DatabaseConfigProvider,
                                      ugRepo: UserGroupRepository)(implicit executionContext: ExecutionContext)
  extends HasDatabaseConfigProvider[JdbcProfile] {

  import profile.api._

  private val ugTable = ugRepo.ugTable
  private val groupTable = ugRepo.groupTable
  private val accountTable = ugRepo.accountTable
  private val userInfoTable = ugRepo.userInfoTable
  private val nasGroupTable = ugRepo.nasGroupTable
  private val nasUserTable = ugRepo.nasUserTable


  def userIsAdmin(id: Option[Int]) = ugRepo.userFindBy(id = id)


  def nasGroupCreate(nas_name: String, pname: String) = db.run(nasGroupTable.filter(_.app_group_name === nas_name).result).flatMap {
    f =>
      if (f.nonEmpty) Future(f.head.id)
      else db.run((nasGroupTable returning nasGroupTable.map(_.id)) += NasGroup(nas_name = nas_name, pname = pname))
  }

  def nasGroupIdUpdate(id: Int, nas_id: Int) = db.run {
    nasGroupTable.filter(_.id === id).map(f => (f.app_group_id, f.checked)).update((nas_id, true))
  }

  def nasGroupAll = db.run(nasGroupTable.map(f => f).result)

  def nasGroupFindBy(id: Int) = db.run(nasGroupTable.filter(_.id === id).map(f => f).result).map {
    f =>
      if (f.nonEmpty) f.head
      else NasGroup()
  }

  def nasGroupFindBypName(pName: String) = db.run(nasGroupTable.filter(_.pname === pName).map(f => f).result)

  def nasGroupList(page: Int = 0, limit: Int = 10, query: String = "") = {
    val f = nasGroupTable.filterIf(query.nonEmpty)(_.pname like query)
    db.run(f.sortBy(_.id).drop(page * limit).take(limit).map(f => f).result).zip(db.run(f.length.result))
  }

  def nasUserCreate(nasUser: NasUser) = {
    db.run(nasUserTable.filter(_.app_user_name === nasUser.nas_name).map(f => f).result).flatMap {
      user =>
        if (user.nonEmpty) {
          if (user.head.id == nasUser.id) {
            if (user.head.checked) Future(0) else Future(1)
          } else Future(-1)
        }
        else db.run(nasUserTable += nasUser)
    }
  }

  def nasUserIdUpdate(id: Int, nas_id: Int) = db.run {
    nasUserTable.filter(_.id === id).map(f => (f.app_user_id, f.checked)).update(nas_id, true)
  }

  def nasUserGidUpdate(id: Int, gid: Int) = db.run {
    nasUserTable.filter(_.id === id).map(f => (f.group_id)).update(gid)
  }

  def userGetNasUser(id: Int) = db.run(nasUserTable.filter(_.id === id).map(f => f).result)

  def userGetNasUser1(userId: Int) = {
    val res = for {
      //      a <- accountTable
      //      u <-nasUserTable
      (a, u) <- userInfoTable joinLeft nasUserTable on (_.accountId === _.id)
    } yield (a.username, a.mobile, u.map(_.app_user_name), u.map(_.group_id), a.accountId)
    db.run(res.filter(_._5 === userId).result)
  }

  def nasUserAll = db.run(nasUserTable.map(f => f).result)

  def nasUserList(page: Int = 0, limit: Int = 10, query: String = "", is_Active: Option[Int] = None) = {
    val f = accountTable.filterIf(query.nonEmpty)(_.username.like("%"+query+"%")).filterOpt(is_Active)(_.is_active === _)
    val res = for {
      (a, u) <- f.sortBy(_.id).drop(page * limit).take(limit) joinLeft nasUserTable on (_.id === _.id)
    } yield (a.id, a.username, a.is_active, u.map(_.app_user_name), u.map(_.group_id), u.map(_.locked), u.map(_.checked))
    db.run(res.result).zip(db.run(f.length.result))
  }

  def userDefaultNasGroup(accId: Int) = {
    //    db.run(ug.ugTable.filter(_.uid == uid ).map(f=>f.gid).result).flatMap{f=>
    //      ug.groupTable.filter(_.id===f.head).result.flatMap(f=>ug.nasGroupTable.filter(_.id===f).result.map(f=
    db.run {
      userInfoTable.filter(_.accountId === accId).filter(_.company === 101).map(f => f.id).result
    }.flatMap {
      userInfoId =>
        val userid = if (userInfoId.nonEmpty) {
          userInfoId.head.getOrElse(0)
        } else {
          0
        }
        val nasGroup = for {
          u <- ugTable.filter(_.uid === userid)
          g <- groupTable if u.gid === g.id
          t <- nasGroupTable if g.nas_gid === t.id
        } yield (t)
        db.run(nasGroup.result)
    }
  }

  def setGroupId(id: Long, gid: Int) = db.run {
    groupTable.filter(_.id === id).map(f => f.nas_gid).update(gid)
  }

}
